/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package AlmacenTemp;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Clase estática que sirve como interfaz para el sistema de
 * almacenamiento temporal para las páginas HTML recolectadas
 * por el recolector y procesadas por el procesador
 * @author Mikel&Igor
 */
public final class AlmacenTemp {
    // Directorio base donde se crearán los archivos temporales
    private static String pathBase = "/Users/mikel/tmp/almacen/";
    /**
     * Método que, dada una página temporal, la guarda en el
     * sistema de almacenamiento
     * @param pag Página a ser guardada
     * @throws IOException Excepción que salta cuanda haya problemas al guardar la página
     *
     */
    public static void guardar(PagTemp pag) throws IOException
    {
        // Lo primero de todo, mirar si el directorio base existe
        File dir = new File(pathBase);
        if(!dir.isDirectory())
            dir.mkdirs(); // Si no existe la ruta, hacer los mkdir necesarios para crearla

        //Crear una instancia de fichero
        File f = new File(pathBase + pag.URLAsFileName());
        //crear el fichero si no existe
        f.createNewFile();

        //Obtener el escritor
        FileWriter writer= new FileWriter(f);
        //Escribir el contenido del fichero
        writer.write(pag.getHTML());
        //Guardar los cambios al fichero
        writer.flush();

        writer.close();
    }

    /**
     * Metodo que devuelve la página temporal más antigua
     * @return La página temporal o null si ya no hay más páginas
     */
    public static PagTemp sacar()
    {
/** codigo para sacar fichero al azar **/
//        // Obtener el directorio
//        File dir = new File(pathBase);
//        String ls[] = dir.list();
//
//        // Si el directorio está vacío:
//        if (ls.length == 0)
//        {
//            throw new IOException();
//            // Salir
//        }
//
//        // Crear una pag vacía para ir rellenando
//        PagTemp pag = new PagTemp();
//
//        // Generar un número aleatorio entre 0 y ls.length-1
//        int ran = (int) ( Math.random()*(ls.length-1) );
//        String fileName = ls[ran];


        // Crear una pag vacía para ir rellenando
        PagTemp pag = new PagTemp();
        
        try {
            synchronized (AlmacenTemp.class) {
                File fich = ultimoModificado();
                // Asignarle la URL convirtiendo el filename
                pag.setURLWithFileName(fich.getName());
                // Leer el contenido del fichero a un string y asignárselo al HTML
                pag.setHTML(leerFichero(fich));

                // Borrar el archivo ya leido
                fich.delete();
            }

        } catch (Exception ex) {
            //Si tenemos una excepción significa que ultimoModificado no tiene más ficheros
            return null;
        }
        //Si todo ha ido bien, devolver la pagina
        return pag;
    }

    /**
     * Lee de manera eficiente un fichero pasando todo su contenido a un String
     * Método privado, de ayuda para el método Sacar
     * @param f El fichero del que leer
     * @return El contenido del fichero en un solo String
     * @throws IOException Error al leer o al abrir el fichero
     */
    private static String leerFichero(File f) throws IOException
    {
        // Obtener el lector
        FileReader fr = new FileReader(f);
        BufferedReader br = new BufferedReader(fr);

        String linea;
        StringBuilder res = new StringBuilder();
        // Leer líneas hasta que acabe el fichero e ir concatenándolas
        // en un StringBuilder
        while ((linea = br.readLine()) != null) {
            res.append(linea);
            res.append('\n');
        }

        // Cerrar los lectores
        br.close();
        fr.close();
        
        return res.toString();
    }

    /**
     * Función que devuelve el fichero más antiguo dentro del pathBase
     * @return El fichero más antiguo
     * @throws IOException Si no hay ficheros, lanza esta excepción
     */
    private static File ultimoModificado() throws Exception
    {   
        File dir = new File(pathBase);
        // Crear un array de files en los que solo hay archivos, no carpetas
        File[] files = dir.listFiles(new FileFilter() {
                public boolean accept(File file) {
                        return file.isFile();
                }
        });
        if ( files.length == 0 ) {
            throw new IOException();
        }
        long masViejo = Long.MAX_VALUE;
        File elegido = null;
        // Para todos los archivos en "files"
        for (File file : files) {
            // Si el archivo actual tiene una fecha anterior al mas viejo visto
            if (file.lastModified() < masViejo) {
                    elegido = file;
                    masViejo = file.lastModified();
            }
        }
        return elegido;
    }

}
